package org.gordonframework.site.forms {
	import org.gordonframework.site.forms.elements.skins.GCheckBoxSkin;	
	import org.gordonframework.site.forms.elements.GCheckBox;	
	import org.gordonframework.site.events.GFormElementEvent;	
	import org.gordonframework.core.collection.GSet;
	import org.gordonframework.site.events.GFormEvent;
	import org.gordonframework.site.forms.elements.GButton;
	import org.gordonframework.site.forms.elements.GElement;
	import org.gordonframework.site.forms.elements.GTextInput;
	import org.gordonframework.site.forms.elements.GTextRow;
	import org.gordonframework.site.forms.elements.formats.GElementSkinFormatFactory;
	import org.gordonframework.site.forms.elements.skins.GButtonSkin;
	import org.gordonframework.site.forms.elements.skins.GElementSkinFactory;
	import org.gordonframework.site.forms.elements.skins.GTextInputSkin;
	import org.gordonframework.site.forms.elements.skins.GTextRowSkin;
	import org.gordonframework.site.views.GView;		

	/**
	 * @author eriarv
	 */
	public class GForm extends GView {
		
		private var _container : GView;
		private var _elements : GSet;
		private var skinFormatFactory : GElementSkinFormatFactory;
		private var skinFactory : GElementSkinFactory;
		
		public function GForm() {
			super();
			_elements = new GSet();
			skinFormatFactory = GElementSkinFormatFactory.getInstance();
			skinFactory = GElementSkinFactory.getInstance();	
			
			_container = new GView();
			addChild(container);
			addElementSkins();
			addEventListeners();
		}
		
		public function validate() : Boolean {
			var invalidCount : int = 0;
			for each ( var element : GElement in elements.toArray() ) {
				if ( !element.isValid ) {
					invalidCount++;
					trace("Invalid element: ", element.type, element.id);
				}
				element.updateInputErrorStatus();
			}
			return ( invalidCount == 0 );
		}
		
		protected function addEventListeners() : void {
			container.addEventListener(GFormElementEvent.CLICK, formElementEventHandler);			container.addEventListener(GFormElementEvent.SUBMIT, formElementEventHandler);
		}
		
		private function formElementEventHandler(event : GFormElementEvent) : void {
			var element : GElement = event.target as GElement;
			
			switch( event.type ) {
				case GFormElementEvent.CLICK:
					if ( element.id == GButton.SUBMIT ) {
						submit();
					} else {
					
					}
				break;
				
				case GFormElementEvent.CHANGE:
				
				break;
				
				case GFormElementEvent.SUBMIT:
					submit();
				break;
			}
		}

		public function addElement( element : GElement ) : Boolean {
			container.addChild( element );
			return elements.add( element );
		}

		protected function addElementSkins() : void {
			skinFactory.setSkinForType(GTextRow.TYPE, GTextRowSkin );			skinFactory.setSkinForType(GTextInput.TYPE, GTextInputSkin);			skinFactory.setSkinForType(GButton.TYPE, GButtonSkin);			skinFactory.setSkinForType(GCheckBox.TYPE, GCheckBoxSkin);
		}
		
		public function get elements() : GSet {
			return _elements;
		}
		
		public function getElementById( id : String ) : GElement {
			return elements.getItemById(id) as GElement;
		}
		
		public function get container() : GView {
			return _container;
		}
		
		public function submit() : void {
			if ( validate() ) {
				dispatchSubmit();
			}
		}
		
		protected function dispatchSubmit() : void {
			dispatchEvent(new GFormEvent(GFormEvent.SUBMIT));
		}
	}
}
